package gnss

/**
 *  20180601-iGMAS-T11TAC008-03V4.0_RTCM协议.pdf     20180205-iGMAS-T11TAC008-03V4.0_RTCM协议.pdf
 *     29  B1Cd  size:615                            29: B1Cd, B2ad, B2bp, B2bd, B3Cd  size:664
 *     30  B2ad  size:615
 *                                                       28: 一期
 */

import (
	"dgo/goutils/utils"
	"fmt"
	"math"
	"time"
)

const (
	A_DAY  = time.Hour * 24
	A_WEEK = A_DAY * 7
)

var (
	CONFIG_OUT_DEBUG_RINEX_HEADER bool = false
)

type RtcmEph struct {
	Sys        byte
	startBitN  int
	RefUtcTime time.Time // 参考解析时间

	// 这个时间有点乱, 不敢乱动 2023-11-15 16:33:34
	// 现在存的: GLO:GPS时间, BD: 北斗时间, GPS GPS时间
	Time       time.Time
	TimeTof    time.Time
	MsgId      uint16
	Satid      uint8
	SISAIoe    int8  // BD 卫星轨道的切向和法向误差精度估计索引值 -16 ~ 15
	SISAIocb   int8  // BD 卫星轨道的径向误差以及卫星钟固定偏差精度估计索引值	-16 ~ 15
	SISAIoc1   uint8 // BD 卫星钟频偏精度估计索引值 0 ~ 7
	SISAIoc2   uint8 // BD 卫星钟频漂精度估计索引值 0 ~ 7
	Week       uint32
	SatType    uint8
	IODnav     uint16
	Iode       uint16
	Sva        float64 // GPS SV Acc.	(URA)
	CodeType   uint8   // GPS L2 测距码类型   / QZSS Codes on L2 Channel
	Aode       float64
	Aodc       float64
	Idot       float64
	Toc        float64
	F2         float64
	F1         float64
	F0         float64
	Iodc       uint16
	Crs        float64
	Del_n0     float64 // DeltaN
	Del_n0_dot float64 //
	M0         float64
	Cuc        float64
	E          float64
	Cus        float64
	DelA       float64
	A          float64
	Adot       float64
	Toe        float64
	Cic        float64
	OMG0       float64
	Cis        float64
	I0         float64
	I0_DOT     float64
	Crc        float64
	OmgSmall   float64
	Omg        float64
	OMG_Dot    float64
	TGD1       float64 //  GAL(BGD(E1, E5a))
	TGD2       float64 //  GAL(BGD(E1, E5b))
	Isc_0      float64
	Isc_1      float64
	Isc_2      float64
	Isc_3      float64
	Isc_4      float64
	Svh        uint8 // 卫星健康标志   GAL(OSHS)(DF314)      Galileo E5b 信号健康状态(DF316
	Svh_1      uint8 // 卫星中                              Galileo E1-B 信号健康状态(DF287
	Dvs_0      uint8 // 数据有效状态  GAL  OSDVS(DF315)   Galileo E5b 数据有效状态 (DF317)
	Dvs_1      uint8 // 数据有效状态                       Galileo E1-B 数据有效状态(DF288
	DIF        uint8
	SIF        uint8
	AIF        uint8
	SISMA      uint8
	Top        uint32
	PFlag      uint8 // L2 P 码数据标志
	Fit        uint8 // 拟合间隔 //DF137  0：曲线适合间隔是4 小时,  1：曲线适合间隔多于4 小时

	Frqsn int8       //GLO 卫星频率通道号 DF040  (-7 ~ 13)
	TK    uint32     // GLO
	Vel   [3]float64 // GLO Velocity(ecef) (m/s)
	Pos   [3]float64 // GLO Position(ecef) (m)
	Acc   [3]float64 // GLO Acceleration (ecef)  (m/s^2)
	Gamn  float64    // GLO Relative freq bias
	Taun  float64    // GLO Sv Clock bias(s)
	En    uint8      // GLO en

	msgver uint8 // msg版本 北斗星历 1: 旧版本29

	debugRawBuf []byte // config_debug_head_rinex时保存
}

const (
	DS_B1I byte = 0
	DS_B1C byte = 1
	DS_B2A byte = 2
	DS_B2B byte = 3
	DS_B3C byte = 4
)

func NewRtcmEph() *RtcmEph {
	rval := &RtcmEph{}
	return rval
}

/***
 * 0: 比较失败, 不可比较
 * 1: 本身比较新
 * 2: c1 比较新
 */
func (this *RtcmEph) CompareLatest(c1 *RtcmEph) int {
	if this.Satid != c1.Satid {
		return 0
	}

	if this.Sys != c1.Sys {
		return 0
	}

	if c1.Week > this.Week {
		return 2
	}

	if c1.Toe > this.Toe {
		return 2
	}

	return 1
}

/*
*

	RTCMBODY 0: msgid
	RTCMALL 24: msgid
*/
func (this *RtcmEph) SetDecodeStartBitN(startBitN int) {
	this.startBitN = startBitN
}

func (this *RtcmEph) GetPrnStrCode() string {
	return GetPrnStrCode(this.Satid, this.Sys)
}

func (this *RtcmEph) CheckSatIdInvalid() error {
	return CheckSatIdInvalid(this.Satid, this.Sys)
}

func (this *RtcmEph) MakeUUID() string {
	str := fmt.Sprintf("%d-%s-%d-%v", this.MsgId, this.GetPrnStrCode(), this.Week, this.Toe)
	return str
}

func (this *RtcmEph) MakeUUIDEx() string {
	return fmt.Sprintf("%s-%s-%d", this.GetPrnStrCode(), this.Time.Format("2006 01 02 15 04 05"), utils.Crc32([]byte(this.GetRinexStr())))
}

// 0: healthy
// 1: unhealhy
func (this *RtcmEph) Healthy() int8 {
	if this.Svh > 0 {
		// GPS DF102
		// QZSS DF454 Bit 0 (MSb): 0 = all NAV data are OK, 1 = some or all NAV data are bad.
		// Galileo DF314/DF316
		// BeiDou 卫星钟自主健康信息  DF515  0可用，1:不可用
		// DF108 GLO
		//if this.Sys == SYS_GPS || this.Sys == SYS_QZS || this.Sys == SYS_GAL || this.Sys == SYS_BD || this.Sys == SYS_GLO {
		return 1
		//}
	}
	return 0
}

// todo 待完善
func (this *RtcmEph) IsBetter(eph *RtcmEph) bool {
	if this.Sys == SYS_GAL {

	}
	return false
}

// 获取RNX中存放的时间, 各个系统自身的星历时间
func (this *RtcmEph) RnxTime() time.Time {
	if this.Sys == SYS_GLO {
		// GLO Rnx 是UTC时间
		return GPSTime2UTC(this.Time)
	}

	return this.Time
}

func (this *RtcmEph) GetRinexStr() string {
	if this.Sys == SYS_BD {
		if this.MsgId == 30 {
			rstr := this.GetRinexBDFmtStr(DS_B2A)
			return rstr
		}

		if this.MsgId == 29 {
			if this.msgver == 0 { // 20190110-iGMAS-T11TAC008-01V4.1_RINEX数据文件格式.pdf
				rstr := this.GetRinexBDFmtStr(DS_B1C)
				return rstr
			}

			// 20180205-iGMAS-T11TAC008-03V4.0_RTCM协议.pdf
			rstr := ""
			//rstr += this.GetRinexBDFmtStr(DS_B1I)  // B1I, B3I
			rstr += this.GetRinexBDFmtStr(DS_B1C)
			if this.Isc_3 != 0 { // ISCB2bd
				rstr += this.GetRinexBDFmtStr(DS_B2B)
			}

			if this.Isc_1 != 0 { // ISCB2ad
				rstr += this.GetRinexBDFmtStr(DS_B2A)
			}
			return rstr
		}

		rstr := this.GetRinexBDFmtStr(DS_B1I)
		return rstr

		return ""
	} else if this.Sys == SYS_GPS {
		rstr := this.GetRinexGPSFmtStr()
		return rstr
	} else if this.Sys == SYS_GAL {
		rstr := this.GetRinexGALFmtStr()
		return rstr
	} else if this.Sys == SYS_GLO {
		rstr := this.GetRinexGLOFmtStr()
		return rstr
	} else if this.Sys == SYS_QZS {
		rstr := this.GetRinexQZSSFmtStr()
		return rstr
	}
	return ""
}

func (this *RtcmEph) GetRinexBDFmtStr(datasource byte) string {
	// -0
	prn := GetPrnStrCode(this.Satid, this.Sys)
	if prn == "CNN" {
		return ""
	}

	// -0
	rval := prn + " " + this.Time.Format("2006 01 02 15 04 05")

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F1), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F2), 19, " ") + "\n"

	// -1
	//  msgid:30 Isc_0 : B2ad
	//  msgid:29 Isc_0   B1Cd
	if datasource == 0 { // 一期
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Aode)), 19+4, " ")
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Iode)), 19+4, " ")
	}
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crs), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Del_n0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.M0), 19, " ") + "\n"

	// -2
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cuc), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.E), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cus), 19, " ")
	if datasource == 0 { // 一期
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.A), 19, " ") + "\n"
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.DelA), 19, " ") + "\n"
	}

	// -3
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cic), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cis), 19, " ") + "\n"

	// -4
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.I0), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crc), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OmgSmall), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG_Dot), 19, " ") + "\n"

	// -5
	// iGMAS-V3.1_RINEX数据文件格式.pdf
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Idot), 19+4, " ")
	if datasource == DS_B1I {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ")
	} else if datasource == DS_B1C {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 1.00), 19, " ")
	} else if datasource == DS_B2B {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 2.00), 19, " ")
	} else if datasource == DS_B2A {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 4.00), 19, " ")
	} else if datasource == DS_B3C {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 8.00), 19, " ")
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ")
	}
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Week)), 19, " ")
	if datasource == 0 {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ") + "\n"
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Adot), 19, " ") + "\n"
	}

	// -6
	if datasource == DS_B1I { // 一期
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Sva)), 19+4, " ")
	} else {
		buf := make([]byte, 4)
		i := 0
		SetBitU8(buf, i, 4, this.SISMA)
		i += 4
		SetBitI8(buf, i, 5, this.SISAIoe)
		i += 5
		SetBitU64(buf, i, 11, uint64(this.Top))
		i += 11
		SetBitI8(buf, i, 5, this.SISAIocb)
		i += 5
		SetBitU8(buf, i, 3, this.SISAIoc1)
		i += 3
		SetBitU8(buf, i, 3, this.SISAIoc2)
		i += 3
		v := GetBitU(buf, 0, 30)
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(v)), 19+4, " ")
	}
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Svh)), 19, " ")
	if (this.MsgId == 29) && this.msgver == 0 { // // 20190110-iGMAS-T11TAC008-01V4.1_RINEX数据文件格式.pdf
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19, " ")
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Isc_0), 19, " ") + "\n"
	} else if this.MsgId == 30 { // // 20190110-iGMAS-T11TAC008-01V4.1_RINEX数据文件格式.pdf
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD2), 19, " ")
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Isc_0), 19, " ") + "\n"
	} else if datasource == DS_B1C {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ")
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Isc_0), 19, " ") + "\n" //BeiDou ISCB1Cd DF356
	} else if datasource == DS_B2B {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19, " ") // TGDB2ap
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Isc_3), 19, " ") + "\n"
	} else if datasource == DS_B2A {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19, " ")         // TGDB2ap
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Isc_1), 19, " ") + "\n" // BeiDou ISCB2ad DF357
	} else if datasource == DS_B3C {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD2), 19, " ") // TGDB3Cp
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Isc_4), 19, " ") + "\n"
	} else { // DS_B1I
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19, " ")
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD2), 19, " ") + "\n"
	}

	// -7
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	if datasource == 0 {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Aodc)), 19, " ")
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ")
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Iodc)), 19, " ")
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Del_n0_dot), 19, " ") // n0_dot
	}

	if datasource == DS_B1C {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ") + "\n"
	} else if datasource == DS_B2B {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Isc_2), 19, " ") + "\n"
	} else if datasource == DS_B2A {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ") + "\n"
	} else if datasource == DS_B3C {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ") + "\n"
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ") + "\n"
	}

	//// -8
	//rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19+4, " ")
	//rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD2), 19, " ")+ "\n"
	//
	//rval += fmt.Sprintf("     TOE: %f, TOC:%f\n", this.Toe, this.Toc);
	return rval
}

func (this *RtcmEph) GetRinexGALFmtStr() string {

	prn := GetPrnStrCode(this.Satid, this.Sys)
	if prn == "ENN" {
		return ""
	}
	if prn == "E40" {
		prn = "E40"
	}

	var rval string

	if CONFIG_OUT_DEBUG_RINEX_HEADER {
		rval = fmt.Sprintf("DEBUGHEAD:msgid:%d, buf:%s\n", this.MsgId, utils.BufToHexStr(this.debugRawBuf, 0, " "))
	}

	// -0
	rval += prn + " " + this.Time.Format("2006 01 02 15 04 05")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F1), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F2), 19, " ") + "\n"

	// -1
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.IODnav)), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crs), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Del_n0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.M0), 19, " ") + "\n"

	// -2
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cuc), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.E), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cus), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.A), 19, " ") + "\n"

	// -3
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cic), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cis), 19, " ") + "\n"

	// -4
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.I0), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crc), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OmgSmall), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG_Dot), 19, " ") + "\n"

	// -5
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Idot), 19+4, " ")
	buf := make([]byte, 2, 2)
	if this.MsgId == 1045 { // F/NAV
		SetBitU8(buf, 1, 1, 1)
		SetBitU8(buf, 8, 1, 1)
	} else if this.MsgId == 1046 { // I/NAV
		SetBitU8(buf, 0, 1, 1)
		SetBitU8(buf, 2, 1, 1)
		SetBitU8(buf, 9, 1, 1)
	}
	ds := GetBitU16(buf, 0, 10)

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(ds)), 19, " ") //
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Week)), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ") + "\n" // ?

	// -6
	if this.SISMA >= 255 {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(-1)), 19+4, " ")
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.SISMA)), 19+4, " ")
	}

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Svh)), 19, " ") //?
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19, " ")         //?
	//if this.MsgId == 1046 {
	//	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD2), 19, " ") + "\n" //?
	//} else {
	//	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD2), 19, " ") + "\n" //?
	//}
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD2), 19, " ") + "\n" //?

	// -7
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 0.00), 19, " ") + "\n"

	return rval
}

func (this *RtcmEph) GetRinexGLOFmtStr() string {
	// -0
	prn := GetPrnStrCode(this.Satid, this.Sys)
	if prn == "RNN" {
		return ""
	}
	var rval string

	if CONFIG_OUT_DEBUG_RINEX_HEADER {
		rval = fmt.Sprintf("DEBUGHEAD:msgid:%d, buf:%s\n", this.MsgId, utils.BufToHexStr(this.debugRawBuf, 0, " "))
	}

	// -0
	utcT := GPSTime2UTC(this.Time) // GLO使用UTC时间
	rval += prn + " " + utcT.Format("2006 01 02 15 04 05")

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", -this.Taun), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Gamn), 19, " ")

	//sow := float64(utils.GetDayOfWeek(this.Time))*86400.00 + float64(this.TK)
	utcTof := GPSTime2UTC(this.TimeTof)
	_, sow := ToGPSTime(utcTof)
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", sow), 19, " ") + "\n"

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Pos[0])/1000), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Vel[0])/1000), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Acc[0])/1000), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Svh)), 19, " ") + "\n"

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Pos[1])/1000), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Vel[1])/1000), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Acc[1])/1000), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Frqsn)), 19, " ") + "\n"

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Pos[2])/1000), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Vel[2])/1000), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Acc[2])/1000), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.En)), 19, " ") + "\n"
	return rval

}

func (this *RtcmEph) GetRinexGPSFmtStr() string {
	// -0
	prn := GetPrnStrCode(this.Satid, this.Sys)
	if prn == "GNN" {
		return ""
	}

	// -0
	rval := prn + " " + this.Time.Format("2006 01 02 15 04 05")

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F1), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F2), 19, " ") + "\n"

	// -1
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Iode)), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crs), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Del_n0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.M0), 19, " ") + "\n"

	// -2
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cuc), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.E), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cus), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.A), 19, " ") + "\n"

	// -3
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cic), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cis), 19, " ") + "\n"

	// -4
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.I0), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crc), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OmgSmall), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG_Dot), 19, " ") + "\n"

	// -5
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Idot), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", 1.00), 19, " ") // Code on L2 Channel
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Week)), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.PFlag)), 19, " ") + "\n" // ?

	// -6
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Sva)), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Svh)), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Iodc)), 19, " ") + "\n"

	// -7
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	if this.Fit == 0 {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(4.00)), 19, " ") + "\n"
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Fit)), 19, " ") + "\n"
	}
	return rval
}

// GNSS Navigation Message File – QZSS Data Record Description
func (this *RtcmEph) GetRinexQZSSFmtStr() string {
	// -0
	prn := GetPrnStrCode(this.Satid, this.Sys)
	if prn == "JNN" {
		return ""
	}

	// -0
	rval := prn + " " + this.Time.Format("2006 01 02 15 04 05")

	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F1), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.F2), 19, " ") + "\n"

	// -1
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Iode)), 19+4, " ") // ?
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crs), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Del_n0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.M0), 19, " ") + "\n"

	// -2
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cuc), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.E), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cus), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.A), 19, " ") + "\n"

	// -3
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cic), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG0), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Cis), 19, " ") + "\n"

	// -4
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.I0), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Crc), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OmgSmall), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.OMG_Dot), 19, " ") + "\n"

	// -5
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Idot), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.CodeType)), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Week)), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(0)), 19, " ") + "\n" // ?

	// -6
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Sva)), 19+4, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Svh)), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.TGD1), 19, " ")
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Iodc)), 19, " ") + "\n"

	// -7
	rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", this.Toe), 19+4, " ")
	if this.Fit == 0 {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(4.00)), 19, " ") + "\n"
	} else {
		rval += utils.AddPrefixForWidth(fmt.Sprintf("%.12E", float64(this.Fit)), 19, " ") + "\n"
	}
	return rval
}

func (this *RtcmEph) decodeBDTime() {
	//var now = time.Now().UTC()
	//if !this.RefUtcTime.IsZero() {
	//	now = this.RefUtcTime
	//}
	//startTime := GetStartTime(this.Sys)
	//week := float64(now.Sub(startTime).Hours()) / float64(24) / float64(7)
	//cyleTimes := uint32(week / float64(8192))
	//this.Week = cyleTimes*8192 + this.Week
	//this.Time = startTime.Add(A_WEEK * time.Duration(this.Week)).Add(time.Duration(this.Toc*1000) * time.Millisecond)
	this.Week, this.Time = AdjustWeekTime(this.Toc, this.Week, this.Sys, this.RefUtcTime)
}

func (this *RtcmEph) decodeGLOTime() {
	week, tow := ToGPSTime(this.RefUtcTime)
	tod := utils.Cfmod(tow, 86400)
	tow -= tod                        // startOfDay的周内秒
	tof := float64(this.TK) - 10800.0 // 1t -> utc 10800(3h)
	if tof < tod-43200 {
		tof += 86400
	} else if tof > tod+43200 {
		tof -= 86400
	}
	t0 := WeekSOWToTime(week, tow+tof)
	this.TimeTof = UTC2GPSTime(t0)

	toe := this.Toe
	if toe < tod-43200.0 {
		toe += 86400.0
	} else if toe > tod+43200.0 {
		toe -= 86400.0
	}
	// utils.Log.Debugf("Toe:%v", toe)
	this.Toe = toe
	t0 = WeekSOWToTime(week, tow+toe)
	this.Time = UTC2GPSTime(t0)

}

// 没用， 当时板卡
//func (this *RtcmEph) decodeBDUseGpsStartTime() {
//	startTime := GetStartTime(SYS_GPS)
//	var now = time.Now().UTC()
//	if !this.RefUtcTime.IsZero() {
//		now = this.RefUtcTime
//	}
//	week := float64(now.Sub(startTime).Hours()) / float64(24) / float64(7)
//	cyleTimes := uint32(week / float64(8192))
//	this.Week = cyleTimes*8192 + this.Week
//
//	this.Time = startTime.Add(A_WEEK * time.Duration(this.Week)).Add(time.Duration(this.Toc*1000) * time.Millisecond)
//}

func (this *RtcmEph) decodeGALTime() {
	//startTime := GetStartTime(this.Sys)
	//var now = time.Now().UTC()
	//if !this.RefUtcTime.IsZero() {
	//	now = this.RefUtcTime
	//}
	//week := float64(now.Sub(startTime).Hours()) / float64(24) / float64(7)
	//cyleTimes := uint32(week / float64(4096))
	//this.Week = cyleTimes*4096 + this.Week
	//
	//this.Time = startTime.Add(A_WEEK * time.Duration(this.Week)).Add(time.Duration(this.Toc*1000) * time.Millisecond)
	//this.Week = uint32(AdjGpsWeek(int(this.Week) % 1024, this.RefUtcTime));
	//this.Time = Gpst2Time(int(this.Week), this.Toc)

	// 使用上面解码Week数字不对
	this.Week, this.Time = AdjustWeekTime(this.Toc, this.Week, SYS_GAL, this.RefUtcTime)
}

func (this *RtcmEph) decodeGPSTime() {
	var now = time.Now().UTC()
	if !this.RefUtcTime.IsZero() {
		now = this.RefUtcTime
	}
	startTime := GetStartTime(this.Sys)
	week := float64(now.Sub(startTime).Hours()) / float64(24) / float64(7)
	cyleTimes := uint32(week / float64(1024))
	this.Week = cyleTimes*1024 + this.Week

	this.Time = startTime.Add(A_WEEK * time.Duration(this.Week)).Add(time.Duration(this.Toc) * time.Second)

}

func (this *RtcmEph) DecodeEphTime() {
	if this.Sys == SYS_GPS || this.Sys == SYS_SBS {
		this.decodeGPSTime()
	} else if this.Sys == SYS_GAL {
		this.decodeGALTime()
	} else if this.Sys == SYS_BD {
		this.decodeBDTime()
	} else if this.Sys == SYS_GLO {
		this.decodeGLOTime()
	} else if this.Sys == SYS_QZS {
		this.decodeGPSTime()
	} else {
		utils.Log.ErrTypef("GNSS-WARN", "解码时间异常:未知的系统%d", this.Sys)
	}

}

func (this *RtcmEph) Decode1020(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "解码rtcm,eph出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()
	i := this.startBitN
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Frqsn = int8(GetBitU8(buf, i, 5)) - 7
	i += 5

	//utmp8 :=GetBitU(buf, i, 1);
	//i +=1;
	//utmp8 =GetBitU(buf, i, 1);
	//i +=1;
	i += 4

	// DF107  GLONASS 子帧起始的当前天内参考时
	// bits 11-7: 0-23,	bits 6-1: 0-59,	bit 0: 0-1
	tk_h := GetBitU8(buf, i, 5)
	i += 5
	tk_m := GetBitU8(buf, i, 6)
	i += 6
	// tk_s := GetBitU8(buf, i, 1) * 30
	tk_s := GetBitU8(buf, i, 1)
	if tk_s != 0 {
		tk_s = tk_s * 30
	}
	i += 1
	// TODO tk_s * 30 会不会有问题? 解码GLO 源文件可以尝试一下
	this.TK = uint32(tk_h)*3600 + uint32(tk_m)*60 + uint32(tk_s)*30 //
	bn := GetBitU8(buf, i, 1)
	i += 1
	//utils.Log.Debugf("tof:%d, tk_h:%d,tk_m:%d,tk_s:%d", this.TK, tk_h, tk_m, tk_s);

	i += 1 //P2 ignore
	tb := GetBitU8(buf, i, 7)
	i += 7
	this.Vel[0] = GetBitG(buf, i, 24) * P2_20 * 1e3
	i += 24
	this.Pos[0] = GetBitG(buf, i, 27) * P2_11 * 1e3
	i += 27
	this.Acc[0] = GetBitG(buf, i, 5) * P2_30 * 1e3
	i += 5

	this.Vel[1] = GetBitG(buf, i, 24) * P2_20 * 1e3
	i += 24
	this.Pos[1] = GetBitG(buf, i, 27) * P2_11 * 1e3
	i += 27
	this.Acc[1] = GetBitG(buf, i, 5) * P2_30 * 1e3
	i += 5

	this.Vel[2] = GetBitG(buf, i, 24) * P2_20 * 1e3
	i += 24
	this.Pos[2] = GetBitG(buf, i, 27) * P2_11 * 1e3
	i += 27
	this.Acc[2] = GetBitG(buf, i, 5) * P2_30 * 1e3
	i += 5
	i += 1 // P3 ignore

	this.Gamn = GetBitG(buf, i, 11) * P2_40
	i += 11
	i += 2 + 1 // DF122, DF123 ignore
	this.Taun = GetBitG(buf, i, 22) * P2_30
	i += 22

	i += 5 // DF125 ignore

	this.En = GetBitU8(buf, i, 5)
	i += 5

	this.Svh = bn // DF108
	this.Iode = uint16(tb & 0x7F)

	this.Toe = float64(tb)*900 - 10800.0 // 1t -> utc;  900(15 * 60) 15 分钟

	this.startBitN = i

	return 1
}

// GPS
func (this *RtcmEph) Decode1019(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "解码rtcm,eph出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()
	i := this.startBitN
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Week = GetBitU(buf, i, 10)
	i += 10

	if this.Satid == 19 {
		this.Sva = 0.0
	}
	this.Sva = float64(GetBitU8(buf, i, 4))
	i += 4
	this.CodeType = GetBitU8(buf, i, 2)
	i += 2
	this.Idot = float64(GetBitI32(buf, i, 14)) * P2_43 * SC2RAD
	i += 14
	this.Iode = GetBitU16(buf, i, 8)
	i += 8
	this.Toc = float64(GetBitU(buf, i, 16)) * 16.0
	i += 16
	this.F2 = float64(GetBitI32(buf, i, 8)) * P2_55 // DF082  2^-55 s/s2
	i += 8
	this.F1 = float64(GetBitI32(buf, i, 16)) * P2_43
	i += 16
	this.F0 = float64(GetBitI32(buf, i, 22)) * P2_31
	i += 22
	this.Iodc = GetBitU16(buf, i, 10)
	i += 10
	this.Crs = float64(GetBitI32(buf, i, 16)) * P2_5
	i += 16
	this.Del_n0 = float64(GetBitI32(buf, i, 16)) * P2_43 * SC2RAD
	i += 16
	this.M0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD
	i += 32
	this.Cuc = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	this.E = float64(GetBitU(buf, i, 32)) * P2_33
	i += 32
	this.Cus = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	sqrtA := float64(GetBitU(buf, i, 32)) * P2_19
	i += 32
	this.A = sqrtA // * sqrtA // DF092  GPS RootA
	this.Toe = float64(GetBitU(buf, i, 16)) * 16.0
	i += 16
	this.Cic = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	this.OMG0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD
	i += 32
	this.Cis = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	this.I0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD
	i += 32
	this.Crc = float64(GetBitI32(buf, i, 16)) * P2_5
	i += 16
	this.OmgSmall = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD
	i += 32
	this.OMG_Dot = float64(GetBitI32(buf, i, 24)) * P2_43 * SC2RAD
	i += 24
	this.TGD1 = float64(GetBitI32(buf, i, 8)) * P2_31
	i += 8
	this.Svh = GetBitU8(buf, i, 6) // DF102
	i += 6
	this.PFlag = GetBitU8(buf, i, 1)
	i += 1
	this.Fit = GetBitU8(buf, i, 1)
	i += 1 // GPS 拟合间隔

	if this.Sva <= 6 { /* URA index */
		this.Sva = math.Ceil(10.0*math.Pow(2.0, 1.0+(float64(this.Sva)/2.0))) / 10.0
	} else {
		this.Sva = math.Ceil(10.0*math.Pow(2.0, (float64(this.Sva)/2.0))) / 10.0
	}

	this.startBitN = i

	// 手动调用
	//this.decodeGPSTime()
	return 1
}

/*
*

	485 BITS
*/
func (this *RtcmEph) DecodeQZSS1044(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "解码rtcm,eph出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()
	i := this.startBitN
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 4)
	i += 4

	this.Toc = float64(GetBitU(buf, i, 16)) * 16.0 // DF430
	i += 16

	this.F2 = float64(GetBitI32(buf, i, 8)) * P2_55 // DF431
	i += 8
	this.F1 = float64(GetBitI32(buf, i, 16)) * P2_43
	i += 16
	this.F0 = float64(GetBitI32(buf, i, 22)) * P2_31
	i += 22

	this.Iode = GetBitU16(buf, i, 8) // DF434
	i += 8

	this.Crs = float64(GetBitI32(buf, i, 16)) * P2_5 // DF435
	i += 16
	this.Del_n0 = float64(GetBitI32(buf, i, 16)) * P2_43 * SC2RAD
	i += 16
	this.M0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD
	i += 32
	this.Cuc = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	this.E = float64(GetBitU(buf, i, 32)) * P2_33
	i += 32
	this.Cus = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	sqrtA := float64(GetBitU(buf, i, 32)) * P2_19
	i += 32
	this.A = sqrtA // * sqrtA // DF441
	this.Toe = float64(GetBitU(buf, i, 16)) * 16.0
	i += 16
	this.Cic = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	this.OMG0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD
	i += 32
	this.Cis = float64(GetBitI32(buf, i, 16)) * P2_29
	i += 16
	this.I0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF446
	i += 32
	this.Crc = float64(GetBitI32(buf, i, 16)) * P2_5
	i += 16
	this.OmgSmall = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF448
	i += 32
	this.OMG_Dot = float64(GetBitI32(buf, i, 24)) * P2_43 * SC2RAD
	i += 24
	this.I0_DOT = float64(GetBitI32(buf, i, 14)) * P2_43 * SC2RAD //DF450
	i += 14

	this.CodeType = GetBitU8(buf, i, 2) // DF451
	i += 2
	this.Week = GetBitU(buf, i, 10)
	i += 10

	this.Sva = float64(GetBitU8(buf, i, 4)) // DF453
	i += 4

	this.Svh = GetBitU8(buf, i, 6) // DF454
	i += 6

	this.TGD1 = float64(GetBitI32(buf, i, 8)) * P2_31 // DF455
	i += 8

	this.Iodc = GetBitU16(buf, i, 10)
	i += 10

	this.Fit = GetBitU8(buf, i, 1) // DF457
	i += 1

	this.startBitN = i

	if this.Sva <= 6 { /* 按照GPS处理 */
		this.Sva = math.Ceil(10.0*math.Pow(2.0, 1.0+(float64(this.Sva)/2.0))) / 10.0
	} else {
		this.Sva = math.Ceil(10.0*math.Pow(2.0, (float64(this.Sva)/2.0))) / 10.0
	}

	return 1
}

func (this *RtcmEph) DecodeGAL1045_1046(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "解码rtcm,eph出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()
	i := this.startBitN
	this.MsgId = GetBitU16(buf, i, 12)
	if this.MsgId == 1045 {
		if (len(buf)*8 - i) < 496 {
			return -1
		}
	} else {
		if (len(buf)*8 - i) < 504 {
			return -1
		}
	}

	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Week = GetBitU(buf, i, 12)
	i += 12
	this.IODnav = GetBitU16(buf, i, 10)
	i += 10

	this.SISMA = GetBitU8(buf, i, 8)
	i += 8
	this.Idot = float64(GetBitI32(buf, i, 14)) * P2_43 * SC2RAD
	i += 14

	this.Toc = float64(GetBitU(buf, i, 14)) * 60
	i += 14

	this.F2 = float64(GetBitI32(buf, i, 6)) * P2_59
	i += 6
	this.F1 = float64(GetBitI32(buf, i, 21)) * P2_46
	i += 21
	this.F0 = float64(GetBitI32(buf, i, 31)) * P2_34
	i += 31

	this.Crs = float64(GetBitI32(buf, i, 16)) * P2_5 // DF297
	i += 16

	this.Del_n0 = float64(GetBitI32(buf, i, 16)) * P2_43 * SC2RAD // DF298
	i += 16
	this.M0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF299
	i += 32
	this.Cuc = float64(GetBitI32(buf, i, 16)) * P2_29 // DF300
	i += 16
	this.E = float64(GetBitU(buf, i, 32)) * P2_33 // DF301
	i += 32
	this.Cus = float64(GetBitI32(buf, i, 16)) * P2_29 // DF302
	i += 16
	sqrtA := float64(GetBitU(buf, i, 32)) * P2_19 // DF303
	i += 32
	this.A = sqrtA
	this.Toe = float64(GetBitU(buf, i, 14)) * 60.0 // DF304
	i += 14
	this.Cic = float64(GetBitI32(buf, i, 16)) * P2_29 //  DF305
	i += 16
	this.OMG0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF306
	i += 32
	this.Cis = float64(GetBitI32(buf, i, 16)) * P2_29 // DF307
	i += 16
	this.I0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF308
	i += 32
	this.Crc = float64(GetBitI32(buf, i, 16)) * P2_5 // DF308
	i += 16
	this.OmgSmall = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF310
	i += 32
	this.OMG_Dot = float64(GetBitI32(buf, i, 24)) * P2_43 * SC2RAD // DF311
	i += 24

	if this.MsgId == 1046 {
		this.TGD1 = float64(GetBitI32(buf, i, 10)) * P2_32 //Galileo BGD(E1,E5a)  DF312
		i += 10
		this.TGD2 = float64(GetBitI32(buf, i, 10)) * P2_32 //Galileo BGD(E1,E5b) DF313
		i += 10
		this.Svh = GetBitU8(buf, i, 2) // DF316
		i += 2
		this.Dvs_0 = GetBitU8(buf, i, 1) // DF317
		i += 1
		this.Svh_1 = GetBitU8(buf, i, 2) // DF287
		i += 2
		this.Dvs_1 = GetBitU8(buf, i, 1) // DF288
		i += 1

		i++ // DF001 保留

	} else { // 1045
		this.TGD1 = float64(GetBitI32(buf, i, 10)) * P2_32 //Galileo BGD(E1,E5a) DF312
		i += 10
		v1 := GetBitU(buf, i, 2) // DF314
		i += 2
		v2 := GetBitU(buf, i, 1) // DF315
		i += 1
		this.Svh = uint8(v1<<1 + v2)
		i++ // DF001 保留
	}

	this.startBitN = i

	// 手动调用
	// this.Week, this.Time = AdjustWeekTime(this.Toc, this.Week, SYS_GAL, this.RefUtcTime);

	//logger.Debug(this.Time)
	return 1
}

// 20180601-iGMAS-T11TAC008-03V4.0_RTCM协议.pdf
//
//	msgid:30 Isc_0 : B2ad
//	msgid:29 Isc_0   B1Cd
func (this *RtcmEph) Decode30(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "Decode30:解码rtcm,eph出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()
	i := this.startBitN
	if (len(buf)*8 - i) < 615 {
		return -1
	}
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Week = GetBitU(buf, i, 13)
	i += 13

	this.SatType = GetBitU8(buf, i, 2) // DF320;
	i += 2
	this.Iode = GetBitU16(buf, i, 8) // DF321
	i += 8
	this.Top = GetBitU(buf, i, 11) // DF322;
	i += 11

	this.SISAIoe = GetBitI8(buf, i, 5)
	i += 5
	this.SISAIocb = GetBitI8(buf, i, 5)
	i += 5
	this.SISAIoc1 = GetBitU8(buf, i, 3)
	i += 3
	this.SISAIoc2 = GetBitU8(buf, i, 3) //DF326
	i += 3

	i_dot := GetBitI32(buf, i, 15)              // DF327
	this.Idot = float64(i_dot) * P2_44 * SC2RAD //DF   (？查看文档, 不需要* SC2CARD)
	i += 15
	this.Toc = float64(GetBitU(buf, i, 11)) * 300.00 //DF328  星钟参考时刻
	i += 11
	this.F2 = float64(GetBitI32(buf, i, 11)) * P2_66 // DF329 卫星钟频漂
	i += 11
	this.F1 = float64(GetBitI32(buf, i, 22)) * P2_50 // DF330
	i += 22
	this.F0 = float64(GetBitI32(buf, i, 25)) * P2_34 // DF331
	i += 25

	this.Iodc = GetBitU16(buf, i, 10) // DF332
	i += 10
	this.Crs = float64(GetBitI32(buf, i, 24)) * P2_8 // DF333
	i += 24

	i_detal_n0 := GetBitI32(buf, i, 17)
	this.Del_n0 = float64(i_detal_n0) * P2_44 * SC2RAD // DF334 ? * SC2RAD
	i += 17
	this.Del_n0_dot = float64(GetBitI32(buf, i, 23)) * P2_57 * SC2RAD // DF335   单位：π/s2 （）ICD.PDF  p.35
	i += 23
	i_m0 := GetBitI64(buf, i, 33)
	this.M0 = float64(i_m0) * P2_32 * SC2RAD // DF336 ? * SC2RAD
	i += 33
	this.Cuc = float64(GetBitI32(buf, i, 21)) * P2_30 // DF337
	i += 21
	i_e := GetBitU64(buf, i, 33)
	this.E = float64(i_e) * P2_34 // DF338
	i += 33
	this.Cus = float64(GetBitI32(buf, i, 21)) * P2_30 // DF339
	i += 21
	this.DelA = float64(GetBitI32(buf, i, 26)) * P2_9 // DF340  长半轴相对参考值的偏差，详细参考北斗 ICD
	i += 26
	this.Adot = float64(GetBitI32(buf, i, 25)) * P2_21 // DF341  长半轴变化率，详细参考北斗 ICD
	i += 25

	i_toe := GetBitU(buf, i, 11) //DF342
	this.Toe = float64(i_toe) * 300.00
	i += 11
	i_cic := GetBitI32(buf, i, 16) //DF343
	this.Cic = float64(i_cic) * P2_30
	i += 16
	i_omega_0 := GetBitI64(buf, i, 33)              // DF344
	this.OMG0 = float64(i_omega_0) * P2_32 * SC2RAD //  SC2RAD
	i += 33

	//if (this.Satid==22 && this.Toe==208800){
	//	this.Cis = 0;
	//}

	i_cis := GetBitI32(buf, i, 16)
	this.Cis = float64(i_cis) * P2_30 // DF345
	i += 16
	i0 := GetBitI64(buf, i, 33)
	this.I0 = float64(i0) * P2_32 * SC2RAD // DF346  * SC2RAD ?
	i += 33
	i_crc := GetBitI32(buf, i, 24) //DF347
	this.Crc = float64(i_crc) * P2_8
	i += 24

	i_omega := GetBitI64(buf, i, 33) //DF348
	//logger.Debug("i:", i, ",i64:", i_omega, ",omega;", this.OmgSmall,",prn:", this.Satid, ",toe:", this.Toe, ",len:", len(buf),  buf);
	this.OmgSmall = float64(i_omega) * P2_32 * SC2RAD //  (?需要成SC2CARD)
	i += 33

	i_omega_dot := GetBitI32(buf, i, 19)
	this.OMG_Dot = float64(i_omega_dot) * P2_44 * SC2RAD // DF349  (?需要成SC2CARD)
	i += 19

	this.TGD1 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF350  BeiDou TGDB1Cp
	i += 12
	this.TGD2 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF351  BeiDou TGDB2ap
	i += 12
	this.Isc_0 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF358 BeiDou ISCB2ad
	i += 12

	this.Svh = GetBitU8(buf, i, 2) //DF353
	i += 2
	this.DIF = GetBitU8(buf, i, 1) //DF354
	i += 1
	this.SIF = GetBitU8(buf, i, 1) //DF355
	i += 1
	this.AIF = GetBitU8(buf, i, 1) //DF356
	i += 1

	this.SISMA = GetBitU8(buf, i, 4)
	i += 4

	this.startBitN = i

	return 1
}

// 20180601-iGMAS-T11TAC008-03V4.0_RTCM协议.pdf
// size:615
func (this *RtcmEph) Decode29(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "Decode29:解码rtcm,eph出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()
	i := this.startBitN
	if (len(buf)*8 - i) < 615 {
		return -1
	}
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Week = GetBitU(buf, i, 13)
	i += 13

	this.SatType = GetBitU8(buf, i, 2) // DF320;
	i += 2
	this.Iode = GetBitU16(buf, i, 8) // DF321
	i += 8
	this.Top = GetBitU(buf, i, 11) // DF322;
	i += 11

	this.SISAIoe = GetBitI8(buf, i, 5) //DF323
	i += 5
	this.SISAIocb = GetBitI8(buf, i, 5) //DF324
	i += 5
	this.SISAIoc1 = GetBitU8(buf, i, 3) // DF325
	i += 3
	this.SISAIoc2 = GetBitU8(buf, i, 3) //DF326
	i += 3

	i_dot := GetBitI32(buf, i, 15)              // DF327
	this.Idot = float64(i_dot) * P2_44 * SC2RAD //DF   (？查看文档, 不需要* SC2CARD)
	i += 15

	this.Toc = float64(GetBitU(buf, i, 11)) * 300.00 //DF328  星钟参考时刻
	i += 11
	this.F2 = float64(GetBitI32(buf, i, 11)) * P2_66 // DF329 卫星钟频漂
	i += 11
	this.F1 = float64(GetBitI32(buf, i, 22)) * P2_50 // DF330
	i += 22
	this.F0 = float64(GetBitI32(buf, i, 25)) * P2_34 // DF331
	i += 25

	this.Iodc = GetBitU16(buf, i, 10) // DF332
	i += 10
	this.Crs = float64(GetBitI32(buf, i, 24)) * P2_8 // DF333
	i += 24

	i_detal_n0 := GetBitI32(buf, i, 17)
	this.Del_n0 = float64(i_detal_n0) * P2_44 * SC2RAD // DF334 ? * SC2RAD
	i += 17
	this.Del_n0_dot = float64(GetBitI32(buf, i, 23)) * P2_57 * SC2RAD // DF335   单位：π/s2 （）ICD.PDF  p.35
	i += 23
	i_m0 := GetBitI64(buf, i, 33)
	this.M0 = float64(i_m0) * P2_32 * SC2RAD // DF336 ? * SC2RAD
	i += 33
	this.Cuc = float64(GetBitI32(buf, i, 21)) * P2_30 // DF337
	i += 21
	i_e := GetBitU64(buf, i, 33)
	this.E = float64(i_e) * P2_34 // DF338
	i += 33
	this.Cus = float64(GetBitI32(buf, i, 21)) * P2_30 // DF339
	i += 21
	this.DelA = float64(GetBitI32(buf, i, 26)) * P2_9 // DF340  长半轴相对参考值的偏差，详细参考北斗 ICD
	i += 26
	this.Adot = float64(GetBitI32(buf, i, 25)) * P2_21 // DF341  长半轴变化率，详细参考北斗 ICD
	i += 25

	i_toe := GetBitU(buf, i, 11) //DF342
	this.Toe = float64(i_toe) * 300.00
	i += 11
	i_cic := GetBitI32(buf, i, 16) //DF343
	this.Cic = float64(i_cic) * P2_30
	i += 16
	i_omega_0 := GetBitI64(buf, i, 33)              // DF344
	this.OMG0 = float64(i_omega_0) * P2_32 * SC2RAD //  SC2RAD
	i += 33

	//if (this.Satid==22 && this.Toe==208800){
	//	this.Cis = 0;
	//}

	i_cis := GetBitI32(buf, i, 16)
	this.Cis = float64(i_cis) * P2_30 // DF345
	i += 16
	i0 := GetBitI64(buf, i, 33)
	this.I0 = float64(i0) * P2_32 * SC2RAD // DF346  * SC2RAD ?
	i += 33
	i_crc := GetBitI32(buf, i, 24) //DF347
	this.Crc = float64(i_crc) * P2_8
	i += 24

	i_omega := GetBitI64(buf, i, 33) //DF348
	//logger.Debug("i:", i, ",i64:", i_omega, ",omega;", this.OmgSmall,",prn:", this.Satid, ",toe:", this.Toe, ",len:", len(buf),  buf);
	this.OmgSmall = float64(i_omega) * P2_32 * SC2RAD //  (?需要成SC2CARD)
	i += 33

	i_omega_dot := GetBitI32(buf, i, 19)
	this.OMG_Dot = float64(i_omega_dot) * P2_44 * SC2RAD // DF349  (?需要成SC2CARD)
	i += 19

	this.TGD1 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF350  BeiDou TGDB1Cp
	i += 12
	this.TGD2 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF351  BeiDou TGDB2ap
	i += 12
	this.Isc_0 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF352 BeiDou ISCB1Cd
	i += 12

	this.Svh = GetBitU8(buf, i, 2) //DF353
	i += 2
	this.DIF = GetBitU8(buf, i, 1) //DF354
	i += 1
	this.SIF = GetBitU8(buf, i, 1) //DF355
	i += 1
	this.AIF = GetBitU8(buf, i, 1) //DF356
	i += 1

	this.SISMA = GetBitU8(buf, i, 4)
	i += 4

	//if i-this.startBitN !=615{
	//   utils.Log.Warnf("错误的消息")
	//}
	this.startBitN = i

	return 1
}

// 20180205-iGMAS-T11TAC008-03V4.0_RTCM协议.pdf
// size 664
func (this *RtcmEph) Decode29Old(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "Decode29Old:解码rtcm,eph出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()

	i := this.startBitN
	if (len(buf)*8 - i) < 664 {
		return -1
	}
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Week = GetBitU(buf, i, 13)
	i += 13
	this.SISAIoe = GetBitI8(buf, i, 5)
	i += 5
	this.SISAIocb = GetBitI8(buf, i, 5)
	i += 5
	this.SISAIoc1 = GetBitU8(buf, i, 3)
	i += 3
	this.SISAIoc2 = GetBitU8(buf, i, 3)
	i += 3

	i_dot := GetBitI32(buf, i, 15)
	this.Idot = float64(i_dot) * P2_44 * SC2RAD //DF330   (？查看文档, 不需要* SC2CARD)
	i += 15
	this.Iode = GetBitU16(buf, i, 8)
	i += 8
	this.Toc = float64(GetBitU(buf, i, 11)) * 300.00 //DF332  星钟参考时刻
	i += 11
	this.F2 = float64(GetBitI32(buf, i, 11)) * P2_66 // DF333 卫星钟频漂
	i += 11
	this.F1 = float64(GetBitI32(buf, i, 22)) * P2_50 // DF334
	i += 22
	this.F0 = float64(GetBitI32(buf, i, 25)) * P2_34 // DF335
	i += 25

	this.Iodc = GetBitU16(buf, i, 10) // DF336
	i += 10
	this.Crs = float64(GetBitI32(buf, i, 24)) * P2_8 // DF337
	i += 24

	i_detal_n0 := GetBitI32(buf, i, 17)
	this.Del_n0 = float64(i_detal_n0) * P2_44 * SC2RAD // DF338 ? * SC2RAD
	i += 17
	this.Del_n0_dot = float64(GetBitI32(buf, i, 23)) * P2_57 * SC2RAD // DF339   单位：π/s2 （）ICD.PDF  p.35
	i += 23
	i_m0 := GetBitI64(buf, i, 33)
	this.M0 = float64(i_m0) * P2_32 * SC2RAD // DF340 ? * SC2RAD
	i += 33
	this.Cuc = float64(GetBitI32(buf, i, 21)) * P2_30 // DF341
	i += 21
	i_e := GetBitU64(buf, i, 33)
	this.E = float64(i_e) * P2_34 // DF342
	i += 33
	this.Cus = float64(GetBitI32(buf, i, 21)) * P2_30 // DF343
	i += 21
	this.DelA = float64(GetBitI32(buf, i, 26)) * P2_9 // DF344  长半轴相对参考值的偏差，详细参考北斗 ICD
	i += 26
	this.Adot = float64(GetBitI32(buf, i, 25)) * P2_21 // DF345  长半轴变化率，详细参考北斗 ICD
	i += 25

	i_toe := GetBitU(buf, i, 11)
	this.Toe = float64(i_toe) * 300.00
	i += 11
	i_cic := GetBitI32(buf, i, 16)
	this.Cic = float64(i_cic) * P2_30
	i += 16
	i_omega_0 := GetBitI64(buf, i, 33)
	this.OMG0 = float64(i_omega_0) * P2_32 * SC2RAD // DF348  * SC2RAD?
	i += 33

	//if (this.Satid==22 && this.Toe==208800){
	//	this.Cis = 0;
	//}

	i_cis := GetBitI32(buf, i, 16)
	this.Cis = float64(i_cis) * P2_30 // DF349
	i += 16
	i0 := GetBitI64(buf, i, 33)
	this.I0 = float64(i0) * P2_32 * SC2RAD // DF350  * SC2RAD ?
	i += 33
	i_crc := GetBitI32(buf, i, 24)
	this.Crc = float64(i_crc) * P2_8
	i += 24

	i_omega := GetBitI64(buf, i, 33)
	//logger.Debug("i:", i, ",i64:", i_omega, ",omega;", this.OmgSmall,",prn:", this.Satid, ",toe:", this.Toe, ",len:", len(buf),  buf);
	this.OmgSmall = float64(i_omega) * P2_32 * SC2RAD //  (?需要成SC2CARD)
	i += 33

	i_omega_dot := GetBitI32(buf, i, 19)
	this.OMG_Dot = float64(i_omega_dot) * P2_44 * SC2RAD // DF353  (?需要成SC2CARD)
	i += 19

	this.TGD1 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF354  BeiDou TGDB2ap
	i += 12
	this.TGD2 = float64(GetBitI32(buf, i, 12)) * P2_34 // DF355  BeiDou TGDB3Cp
	i += 12
	this.Isc_0 = float64(GetBitI32(buf, i, 12)) * P2_34 // BeiDou ISCB1Cd DF356
	i += 12
	this.Isc_1 = float64(GetBitI32(buf, i, 12)) * P2_34 // BeiDou ISCB2ad DF357
	i += 12
	this.Isc_2 = float64(GetBitI32(buf, i, 12)) * P2_34 // BeiDou ISCB2bp DF358
	i += 12
	this.Isc_3 = float64(GetBitI32(buf, i, 12)) * P2_34 // BeiDou ISCB2bd DF359
	i += 12
	this.Isc_4 = float64(GetBitI32(buf, i, 12)) * P2_34 // BeiDou ISCB3Cd DF360
	i += 12

	this.Svh = GetBitU8(buf, i, 5) //DF361
	i += 5
	this.SISMA = GetBitU8(buf, i, 4)
	i += 4
	this.Top = GetBitU(buf, i, 11) * 300 // * 300
	i += 11

	i += 3 // 保留3Bit

	this.startBitN = i
	this.msgver = 1

	//logger.Debug(fmt.Sprintf("prn:%d, toe:%d, deltaN0:%d, m0:%d, e:%d,i_cic:%d, omega0:%d, i_cis:%d, i_crc:%d, i_omega:%d, i_omega_dot:%d",
	//	this.Satid, i_toe,  i_detal_n0, i_m0, i_e, i_cic, i_omega_0, i_cis, i_crc, i_omega, i_omega_dot));

	return 1
}

func (this *RtcmEph) Decode1042(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "Decode1042:解码rtcm 出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()

	i := this.startBitN
	if (len(buf)*8 - this.startBitN) < 511 {
		return -1
	}
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Week = GetBitU(buf, i, 13)
	i += 13

	i8 := GetBitU8(buf, i, 4)
	if int(i8) >= len(URA_VAL) {
		i8 = 14
	}
	this.Sva = URA_VAL[i8] // DF490  卫星精度
	i += 4

	this.Idot = float64(GetBitI32(buf, i, 14)) * P2_43 * SC2RAD // DF491
	i += 14

	i8 = GetBitU8(buf, i, 5)
	// 20180601-iGMAS-T11TAC008-03V4.0_RTCM协议.pdf
	this.Aode = float64(i8) // AODE DF492
	i += 5

	this.Toc = float64(GetBitU(buf, i, 17)) * 8 //DF493  2^3
	i += 17

	this.F2 = float64(GetBitI32(buf, i, 11)) * P2_66 // DF494 卫星钟频漂
	i += 11

	this.F1 = float64(GetBitI32(buf, i, 22)) * P2_50 // DF495
	i += 22

	this.F0 = float64(GetBitI32(buf, i, 24)) * P2_33 // DF496
	i += 24

	this.Aodc = float64(GetBitU8(buf, i, 5)) // DF497
	i += 5

	this.Crs = float64(GetBitI32(buf, i, 18)) * P2_6 // DF498
	i += 18

	this.Del_n0 = float64(GetBitI32(buf, i, 16)) * P2_43 * SC2RAD // DF499
	i += 16
	this.M0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF500
	i += 32
	this.Cuc = float64(GetBitI32(buf, i, 18)) * P2_31 // DF501
	i += 18
	this.E = float64(GetBitU(buf, i, 32)) * P2_33 // DF502
	i += 32
	this.Cus = float64(GetBitI32(buf, i, 18)) * P2_31 // DF503
	i += 18

	sqrtA := float64(GetBitU(buf, i, 32)) * (P2_19)
	i += 32

	this.A = sqrtA                              // * sqrtA // DF504  RootA 和GPS 算法一致
	this.Toe = float64(GetBitU(buf, i, 17)) * 8 //DF505  2^3
	i += 17

	this.Cic = float64(GetBitI32(buf, i, 18)) * P2_31 // DF506
	i += 18
	this.OMG0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF507
	i += 32
	this.Cis = float64(GetBitI32(buf, i, 18)) * P2_31 // DF508
	i += 18
	this.I0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF509
	i += 32
	this.Crc = float64(GetBitI32(buf, i, 18)) * P2_6 // DF510
	i += 18
	this.OmgSmall = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF511
	i += 32

	this.OMG_Dot = float64(GetBitI32(buf, i, 24)) * P2_43 * SC2RAD // DF512
	i += 24

	this.TGD1 = float64(GetBitI32(buf, i, 10)) * P10_10 // DF513
	i += 10
	this.TGD2 = float64(GetBitI32(buf, i, 10)) * P10_10 // DF514
	i += 10

	this.Svh = GetBitU8(buf, i, 1) //  BeiDou 卫星钟自主健康信息  DF515  0可用，1:不可用
	i += 1

	this.startBitN = i

	// 手动调用
	//this.decodeBDTime()
	return 1
}

func (this *RtcmEph) Decode28(buf []byte) (rval int) {
	defer func() { // 捕捉异常
		if err := recover(); err != nil {
			utils.Log.ErrTypef("GNSS-WARN", "Decode28:解码rtcm 出现了异常:%v\r\n%s", err, utils.BufToHexStr(buf, 0, " "))
			rval = -1
			return
		}
	}()
	i := this.startBitN
	this.MsgId = GetBitU16(buf, i, 12)
	i += 12
	this.Satid = GetBitU8(buf, i, 6)
	i += 6
	this.Week = GetBitU(buf, i, 13)
	i += 13

	this.Svh = GetBitU8(buf, i, 1) //  BeiDou 卫星钟自主健康信息  DF515  0可用，1:不可用
	i += 1

	i8 := GetBitU8(buf, i, 4)
	if int(i8) >= len(URA_VAL) {
		i8 = 14
	}
	this.Sva = URA_VAL[i8] // DF490  卫星精度
	i += 4

	this.Idot = float64(GetBitI32(buf, i, 14)) * P2_43 * SC2RAD // DF491
	i += 14

	if this.Satid == 3 {
		this.Aode = 0
	}

	i8 = GetBitU8(buf, i, 5)
	this.Aode = float64(i8) * P211 // AODE DF492
	i += 5

	this.Toe = float64(GetBitU(buf, i, 17)) * 8 //DF505  2^3
	i += 17

	this.F2 = float64(GetBitI32(buf, i, 11)) * P2_66 // DF494 卫星钟频漂
	i += 11
	this.Aodc = float64(GetBitU8(buf, i, 5)) // DF497
	i += 5
	this.F1 = float64(GetBitI32(buf, i, 22)) * P2_50 // DF495
	i += 22
	this.Crs = float64(GetBitI32(buf, i, 18)) * P2_6 // DF498
	i += 18
	this.F0 = float64(GetBitI32(buf, i, 24)) * P2_33 // DF496
	i += 24
	this.Del_n0 = float64(GetBitI32(buf, i, 16)) * P2_43 * SC2RAD // DF499
	i += 16
	this.M0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF500
	i += 32
	this.OMG_Dot = float64(GetBitI32(buf, i, 24)) * P2_43 * SC2RAD // DF512
	i += 24
	this.E = float64(GetBitU(buf, i, 32)) * P2_33 // DF502
	i += 32

	sqrtA := float64(GetBitU(buf, i, 32)) * (P2_19)
	i += 32
	this.A = sqrtA // * sqrtA // DF504  RootA 和GPS 算法一致

	this.OMG0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF507
	i += 32

	this.I0 = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF509
	i += 32
	this.OmgSmall = float64(GetBitI32(buf, i, 32)) * P2_31 * SC2RAD // DF511
	i += 32
	this.Cuc = float64(GetBitI32(buf, i, 18)) * P2_31 // DF501
	i += 18
	this.Cus = float64(GetBitI32(buf, i, 18)) * P2_31 // DF503
	i += 18
	this.Toc = float64(GetBitU(buf, i, 17)) * 8.0 // DF493
	i += 17
	this.Cic = float64(GetBitI32(buf, i, 18)) * P2_31 // DF506
	i += 18
	this.Cis = float64(GetBitI32(buf, i, 18)) * P2_31 // DF508
	i += 18
	this.Crc = float64(GetBitI32(buf, i, 18)) * P2_6 // DF510
	i += 18
	this.TGD1 = float64(GetBitI32(buf, i, 10)) * P10_10 // DF513
	i += 10
	this.TGD2 = float64(GetBitI32(buf, i, 10)) * P10_10 // DF514
	i += 10

	i += 1 // 保留1Bit

	this.startBitN = i

	// 手动调用
	//this.decodeBDTime()
	return 1
}
